/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package ACV;

import java.awt.image.BufferedImage;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URI;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.zip.Adler32;
import java.util.zip.CheckedInputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
import javax.imageio.ImageIO;

/**
 *
 * @author Calvin
 */
public class Comic{
    
    private String directory = null;
    private ZipFile archive = null;
    private Vector<BufferedImage> pages = null;
    private boolean zipFlag = false;

    public Comic(String dir) {
        this.directory = dir;
        pages = new Vector<BufferedImage>();
        getPagesFromZip(this.directory);
        
    }
    
    /**
     * Method to determine if the comic contains the specified page number 
     * @param pg - page number
     * @return - true if found / false if not found 
     */
    public boolean hasPage(int pg) {
        //if requested page is > 0 AND <= number of pages
        if(pages.size() > 0 && pg > 0 && pg <= pages.size() ) {
            return true;
        } else {
            return false;
        }
    }
    
    /**
     * Method to retrieve a page from the Comic
     * Returns null if not found
     * @param pg - page number to retrieve
     * @return - BufferedImage representation of page
     */
    public BufferedImage getPage(int pg) {
        if (hasPage(pg)) {
            return pages.get(pg - 1); //returns page number - 1 for index value
        } else {
            return null;
        }

    }
    
    public void unZip(String path) {
        try {
            final int BUFFER = 2048;
            BufferedOutputStream dest = null;
            FileInputStream fis = new FileInputStream(path);
            ZipInputStream zis = new ZipInputStream(new BufferedInputStream(fis));
            ZipEntry entry;
            while ((entry = zis.getNextEntry()) != null) {
                System.out.println("Extracting: " + entry);
                int count;
                byte data[] = new byte[BUFFER];
                // write the files to the disk
                FileOutputStream fos = new FileOutputStream(entry.getName());
                dest = new BufferedOutputStream(fos, BUFFER);
                while ((count = zis.read(data, 0, BUFFER))
                        != -1) {
                    dest.write(data, 0, count);
                }
                dest.flush();
                dest.close();
            }
            zis.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    
    private void getPagesFromZip(String path){
        try {
            FileInputStream fis = new FileInputStream(path);
            CheckedInputStream checksum = new CheckedInputStream(fis, new Adler32());
            ZipInputStream zis = new ZipInputStream(new BufferedInputStream(checksum));

            ZipEntry ze = zis.getNextEntry();
            while (ze != null) {

                pages.add(ImageIO.read(zis));
                zis.closeEntry();
                ze = zis.getNextEntry();

            }
            zis.close(); zis = null;
            fis.close(); fis = null;
            checksum.close(); checksum = null;
            System.gc();
            

        } catch (IOException ex) {
            System.out.println("Error getting Images from ZIP:");
            ex.printStackTrace();
        }


    }
    
    @Override
    public void finalize(){
        try {
            super.finalize();
            for(BufferedImage bi : pages) {
                bi.flush();
            }
            pages.clear();
        } catch (Throwable ex) {
            Logger.getLogger(Comic.class.getName()).log(Level.SEVERE, null, ex);
        }
        
    }
    
}
